﻿using Newtonsoft.Json;
using ThresholdAssistant.DataContract.Extensions;
using ThresholdAssistant.Enums;
using System;
using System.Text.Json.Serialization;

namespace ThresholdAssistant.DataContract.Result
{
    /// <summary>
    /// 返回结果契约基类
    /// </summary>
    [Serializable]
    public class ContractResult
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public ContractResult()
        {
            Success = false;
            ErrorCode = $"{(int)ErrorTypeEnum.BusinessFailed}";
            ErrorMessage = ErrorTypeEnum.BusinessFailed.GetDescription();
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        public ContractResult(Enum enumType)
        {
            Success = false;
            ErrorCode = enumType.GetHashCode().ToString();
            ErrorMessage = enumType.GetDescription();
        }

        /// <summary>
        /// 操作结果
        /// </summary>
        [JsonProperty("success"), JsonPropertyName("success")]
        public bool Success { get; set; }

        /// <summary>
        /// 错误状态码
        /// </summary>
        [JsonProperty("code"), JsonPropertyName("code")]
        public string ErrorCode { get; set; }

        /// <summary>
        /// 错误信息，成功将返回空
        /// </summary>
        [JsonProperty("message"), JsonPropertyName("message")]
        public string ErrorMessage { get; set; }

        /// <summary>
        /// 统一返回当前服务器时
        /// </summary>
        [JsonProperty("service_time"), JsonPropertyName("service_time")]
        public DateTime ServiceTime { get; set; } = DateTime.Now.ToCstTime();

        /// <summary>
        /// 业务流水号
        /// </summary>
        [JsonProperty("serial_no"), JsonPropertyName("serial_no")]
        public string SerialNo { get; set; } = Guid.NewGuid().ToString("N").ToUpper();

        /// <summary>
        /// 设置错误信息
        /// </summary>
        /// <param name="enumType">错误信息</param>
        public ContractResult SetError<T>(T enumType) where T : Enum
        {
            Success = false;
            ErrorCode = enumType.GetHashCode().ToString();
            ErrorMessage = enumType.GetDescription();
            return this;
        }

        /// <summary>
        /// 设置错误信息
        /// </summary>
        /// <param name="enumType">错误信息</param>
        /// <param name="serialNo">业务流水号</param>
        public ContractResult SetError<T>(T enumType, string serialNo) where T : Enum
        {
            Success = false;
            if (!string.IsNullOrWhiteSpace(serialNo))
            {
                SerialNo = serialNo;
            }
            ErrorMessage = enumType.GetDescription();
            ErrorCode = enumType.GetHashCode().ToString();
            return this;
        }

        /// <summary>
        /// 设置错误信息
        /// </summary>
        /// <param name="code">错误码</param>
        /// <param name="message">错误消息</param>
        /// <param name="serialNo"></param>
        public ContractResult SetError(string code, string message, string serialNo = "")
        {
            Success = false;
            ErrorCode = code;
            ErrorMessage = message;
            if (!string.IsNullOrWhiteSpace(serialNo))
            {
                SerialNo = serialNo;
            }
            return this;
        }

        /// <summary>
        /// 检查是否成功
        /// </summary>
        public bool IsSuceccful()
        {
            return Success;
        }

        /// <summary>
        /// 设置成功返回信息
        /// </summary>
        public ContractResult SetSuceccful(string serialNo = "")
        {
            Success = true;
            if (!string.IsNullOrWhiteSpace(serialNo))
            {
                SerialNo = serialNo;
            }
            ErrorMessage = ErrorTypeEnum.SUCCESS.GetDescription();
            ErrorCode = ErrorTypeEnum.SUCCESS.GetHashCode().ToString();
            return this;
        }

        public ContractResult SetError(object delImgUrlTokenError)
        {
            throw new NotImplementedException();
        }
    }

    /// <summary>
    /// 返回结果契约
    /// </summary>
    /// <typeparam name="T"></typeparam>
    [Serializable]
    public class ContractResult<T> : ContractResult
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public ContractResult()
        {
            Success = false;
            ErrorCode = $"{(int)ErrorTypeEnum.BusinessFailed}";
            ErrorMessage = ErrorTypeEnum.BusinessFailed.GetDescription();
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        public ContractResult(Enum enumType)
        {
            Success = false;
            ErrorCode = enumType.GetHashCode().ToString();
            ErrorMessage = enumType.GetDescription();
        }

        /// <summary>
        /// 数据
        /// </summary>
        [JsonProperty("data"), JsonPropertyName("data")]
        public T Data { get; set; }

        /// <summary>
        /// 设置成功返回信息
        /// </summary>
        /// <param name="data"></param>
        /// <param name="serialNo"></param>
        public ContractResult<T> SetSuceccful(T data = default, string serialNo = "")
        {
            Success = true;
            if (data != null)
            {
                Data = data;
            }

            if (!string.IsNullOrWhiteSpace(serialNo))
            {
                SerialNo = serialNo;
            }

            ErrorMessage = ErrorTypeEnum.SUCCESS.GetDescription();
            ErrorCode = ErrorTypeEnum.SUCCESS.GetHashCode().ToString();
            return this;
        }

        /// <summary>
        /// 设置错误信息
        /// </summary>
        /// <param name="enumType">错误信息</param>
        public new ContractResult<T> SetError<E>(E enumType) where E : Enum
        {
            Success = false;
            ErrorCode = enumType.GetHashCode().ToString();
            ErrorMessage = enumType.GetDescription();
            return this;
        }

        /// <summary>
        /// 设置错误信息
        /// </summary>
        /// <param name="enumType">错误信息</param>
        /// <param name="serialNo">业务流水号</param>
        public new ContractResult<T> SetError<E>(E enumType, string serialNo) where E : Enum
        {
            Success = false;
            if (!string.IsNullOrWhiteSpace(serialNo))
            {
                SerialNo = serialNo;
            }
            ErrorMessage = enumType.GetDescription();
            ErrorCode = enumType.GetHashCode().ToString();
            return this;
        }

        /// <summary>
        /// 设置错误信息
        /// </summary>
        /// <param name="code">错误码</param>
        /// <param name="message">错误消息</param>
        /// <param name="serialNo"></param>
        public new ContractResult<T> SetError(string code, string message, string serialNo = "")
        {
            Success = false;
            ErrorCode = code;
            ErrorMessage = message;
            if (!string.IsNullOrWhiteSpace(serialNo))
            {
                SerialNo = serialNo;
            }
            return this;
        }
    }
}